//
//  TFQueueRequest.m
//  TFFoundation
//
//  Created by TFAppleWork-Summer on 2017/3/21.
//  Copyright © 2017年 TFAppleWork-Summer. All rights reserved.
//

#import "TFQueueRequest.h"
#import "TFRequest.h"

NSString * const kTFQueueRequestConfigPathKey = @"TFQueueRequestConfig";

NSString * const kTFQueueRequestConfigParamsKey = @"TFQueueRequestConfigParams";

NSString * const kTFQueueRequestConfigRequestClassKey = @"TFQueueRequestConfigRequestClass";

NSString * const kTFQueueRequestConfigReponseMapClassNameKey = @"TFQueueRequestConfigReponseMapClassName";

@interface TFQueueRequest ()

@property (nonatomic, strong, readwrite, nonnull) NSArray<__kindof TFRequest *> *requestArray;

@property (nonatomic, assign, readwrite) NSInteger finishedRequestCount;

@end

@implementation TFQueueRequest

- (instancetype)initWithRequestArray:(NSArray<TFRequest *> *)requestArray {
    self = [super init];
    if (self) {
        _requestType = TFQueueRequestTypeConcurrent;
        _requestArray = requestArray;
    }
    return self;
}

- (instancetype)initWithRequestConfigArray:(NSArray<NSDictionary<kTFQueueRequestConfigKey,id> *> *)configArray {
    NSMutableArray *requestArray = [NSMutableArray array];
    for (NSDictionary *configDic in configArray) {
        Class requestClass = configDic[kTFQueueRequestConfigRequestClassKey];
        BOOL isTFRequestClass = [requestClass isSubclassOfClass:[TFRequest class]];
        NSAssert(isTFRequestClass, @"request class must be the subclass of TFRequest.");
        TFRequest *request = [[requestClass alloc] init];
        request.params = configDic[kTFQueueRequestConfigParamsKey];
        request.path = configDic[kTFQueueRequestConfigPathKey];
        request.responseJsonObjectMapClassName = configDic[kTFQueueRequestConfigReponseMapClassNameKey];
        [requestArray addObject:request];
    }
    return [self initWithRequestArray:requestArray];
}

- (void)startRequestWithResponse:(TFQueueRequestResponseBlock)responseBlock completionBlock:(TFQueueRequestCompletionBlock)completionBlock {
    
    _finishedRequestCount = 0;
    __block NSInteger totalRequestCount = self.requestArray.count;
    switch (_requestType) {
        case TFQueueRequestTypeConcurrent:
        {
            __block NSMutableArray *dataTaskArray = [NSMutableArray array];
            for (__kindof TFRequest *request in _requestArray) {
                typeof(self) __block blockSelf = self;
            [request startRequestWithResponseBlock:^(__kindof TFRequest * _Nonnull request, id  _Nullable response, NSError * _Nullable error) {
                
                @synchronized (blockSelf) {
                    blockSelf.finishedRequestCount +=1;
                }
                   if (responseBlock) {
                       BOOL isContinue = responseBlock(blockSelf,request,[blockSelf.requestArray indexOfObject:request],response,error);
                       if (!isContinue) {
                           //取消所有的请求
                           for (NSURLSessionTask *task in dataTaskArray) {
                               if (task.state==NSURLSessionTaskStateRunning) {
                                   [task cancel];
                               }
                           }
                       }
                       if (blockSelf.finishedRequestCount==totalRequestCount) {
                           if (completionBlock) {
                               completionBlock(blockSelf);
                           }
                       }
                   }
                }];
                @synchronized (dataTaskArray) {
                    [dataTaskArray addObject:request.sessionTask];
                }
            }
        }
            break;
        case TFQueueRequestTypeSerial: {
            //开始串行请求
            [self p_startSerialRequestWithResponse:responseBlock completionBlock:completionBlock];
        }
            break;
        default:
            break;
    }
}

- (void)p_startSerialRequestWithResponse:(TFQueueRequestResponseBlock)responseBlock completionBlock:(TFQueueRequestCompletionBlock)completionBlock {
    typeof(self) __block blockSelf = self;
    TFRequest *request = self.requestArray[_finishedRequestCount];
    __block NSInteger totalRequestCount = self.requestArray.count;
    [request startRequestWithResponseBlock:^(__kindof TFRequest * _Nonnull request, id  _Nullable response, NSError * _Nullable error) {
        blockSelf.finishedRequestCount ++;
        BOOL isContinue = responseBlock(blockSelf,request,[blockSelf.requestArray indexOfObject:request],response,error);
        if (!isContinue) {
            return;
        }
        else if (blockSelf.finishedRequestCount==totalRequestCount) {
            if (completionBlock) {
                completionBlock(blockSelf);
            }
        }
        else {
            [blockSelf p_startSerialRequestWithResponse:responseBlock completionBlock:completionBlock];
        }
    }];
}

@end
